from django.shortcuts import render
from django.views import View
import json, pickle, base64
from django import http
from goods.models import SKU
from meiduo_mall.utils.response_code import RETCODE
from django_redis import get_redis_connection


import logging

logger = logging.getLogger('django')

# Create your views here.

class CartsView(View):

    def post(self, request):

        json_dict = json.loads(request.body.decode())
        sku_id = json_dict.get('sku_id')
        count = json_dict.get('count')
        selected = json_dict.get('selected', True)

        if all([sku_id, count]) is False:
            return http.HttpResponseForbidden('缺少必传参数')

        try:
            sku = SKU.objects.get(id = sku_id, is_launched=True)
        except SKU.DoesNotExist:
            return http.HttpResponseForbidden('sku_id不存在')

        try:
            count = int(count)
        except Exception as e:
            logger.error(e)
            return http.HttpResponseForbidden('参数类型有误')

        if isinstance(selected, bool) is False:
            return http.HttpResponseForbidden('参数类型有误')

        user = request.user
        if user.is_authenticated:

            redis_conn = get_redis_connection('carts')
            pl = redis_conn.pipeline()
            pl.hincrby('cart_%s' % user.id, sku_id, count)
            if selected:
                pl.sadd('selected_%s' %user.id, sku_id)
            pl.execute()
            return http.JsonResponse({'code': RETCODE.OK, 'errmsg': '添加购物车成功'})

        else:
            cart_str = request.COOKIES.get('carts')
            if cart_str:
                bytes_str = cart_str.encode()
                bytes_un = base64.b64decode(bytes_str)
                cart_dict = pickle.loads(bytes_un)

                # cart_dict = pickle.loads(base64.b64decode(cart_str.encode()))

                if sku_id in cart_dict:
                    origin_count = cart_dict[sku_id]['count']
                    count += origin_count
            else:
                cart_dict = {}

            cart_dict[sku_id] = {'count': count, 'selected': selected}

            bytes_un = pickle.dumps(cart_dict)
            bytes_str = base64.b64encode(bytes_un)
            cart_str = bytes_str.decode()

            response = http.JsonResponse({'code': RETCODE.OK, 'errmsg': '添加购物车成功'})

            response.set_cookie('carts', cart_str)
            return response

    def get(self, request):

        user = request.user
        if user.is_authenticated:
            redis_conn = get_redis_connection('carts')
            redis_carts = redis_conn.hgetall('cart_%s' % user.id)
            selected_ids = redis_conn.smembers('selected_%s' % user.id)
            cart_dict = {}
            for sku_id_bytes in redis_carts:
                cart_dict[int(sku_id_bytes)] = {
                    'count': int(redis_carts[sku_id_bytes]),
                    'selected': sku_id_bytes in selected_ids
                }

        else:

            cart_str = request.COOKIES.get('carts')
            if cart_str:
                cart_dict = pickle.loads(base64.b64decode(cart_str.encode()))
            else:
                return render(request, 'cart.html')

        sku_qs = SKU.objects.filter(id__in=cart_dict.keys())
        sku_list = []
        for sku_model in sku_qs:
            count = cart_dict[sku_model.id]['count']
            sku_list.append({
                'id': sku_model.id,
                'name': sku_model.name,
                'default_image_url': sku_model.default_image.url,
                'price': str(sku_model.price),
                'count': count,
                'selected': str(cart_dict[sku_model.id]['selected']),
                'amount': str(sku_model.price * count)
            })

        return render(request, 'cart.html', {'cart_skus': sku_list})

    def put(self, request):

        json_dict = json.loads(request.body.decode())
        sku_id = json_dict.get('sku_id')
        count = json_dict.get('count')
        selected = json_dict.get('selected')

        if all([sku_id, count]) is False:
            return http.HttpResponseForbidden('缺少必传参数')

        try:
            sku = SKU.objects.get(id = sku_id, is_launched=True)
        except SKU.DoesNotExist:
            return http.HttpResponseForbidden('sku_id不存在')

        try:
            count = int(count)
        except Exception as e:
            logger.error(e)
            return http.HttpResponseForbidden('参数类型有误')

        if isinstance(selected, bool) is False:
            return http.HttpResponseForbidden('参数类型有误')

        sku_dict = {
            'id': sku.id,
            'name': sku.name,
            'default_image_url':sku.default_image.url,
            'price': str(sku.price),
            'count': count,
            'selected': selected,
            'amount': str(sku.price * count)
        }

        response = http.JsonResponse({'code': RETCODE.OK, 'errmsg': '修改购物车数据成功', 'cart_sku': sku_dict})

        user = request.user
        if user.is_authenticated:
            redis_conn = get_redis_connection('carts')
            redis_conn.hset('cart_%s' % user.id, sku_id, count)
            if selected:
                redis_conn.sadd('selected_%s' % user.id, sku_id)
            else:
                redis_conn.srem('selected_%s' % user.id, sku_id)
        else:
            cart_str = request.COOKIES.get('carts')
            if cart_str:
                cart_dict = pickle.loads(base64.b64decode(cart_str.encode()))
            else:
                return http.HttpResponseForbidden('没有cookies数据')

            cart_dict[sku_id] = {
                'count': count,
                'selected': selected
            }
            cart_str = base64.b64encode(pickle.dumps(cart_dict)).decode()
            response.set_cookie('carts', cart_str)

        return response

    def delete(self, request):

        json_dict = json.loads(request.body.decode())
        sku_id = json_dict.get('sku_id')
        try:
            sku = SKU.objects.get(id = sku_id, is_launched=True)
        except SKU.DoesNotExist:
            return http.HttpResponseForbidden('sku_id无效')

        user = request.user
        if user.is_authenticated:
            redis_conn = get_redis_connection('carts')
            pl = redis_conn.pipeline()
            pl.hdel('cart_%s' % user.id, sku_id)
            pl.srem('selected_%s' % user.id, sku_id)
            pl.execute()
            return http.JsonResponse({'code': RETCODE.OK, 'errmsg': '删除购物车成功'})

        else:
            cart_str = request.COOKIES.get('carts')
            if cart_str:
                cart_dict = pickle.loads(base64.b64decode(cart_str.encode()))
            else:
                return http.HttpResponseForbidden('没有cookie，删除什么')
            if sku_id in cart_dict:
                del cart_dict[sku_id]
            response = http.JsonResponse({'code':RETCODE.OK, 'errmsg': '删除购物车成功'})
            if not cart_dict:
                response.delete_cookie('carts')
                return response
            cart_str = base64.b64encode(pickle.dumps(cart_dict)).decode()
            response.set_cookie('carts', cart_str)
            return response

class CartSelectedAllView(View):

    def put(self, request):
        json_dict = json.loads(request.body.decode())
        selected = json_dict.get('selected')
        if isinstance(selected, bool) is False:
            return http.HttpResponseForbidden('参数类型有误')
        user = request.user
        if user.is_authenticated:
            redis_conn = get_redis_connection('carts')
            if selected:
                redis_carts = redis_conn.hgetall('cart_%s' % user.id)
                redis_conn.sadd('selected_%s' % user.id, *redis_carts.keys())
            else:
                redis_conn.delete('selected_%s' % user.id)
                # redis_conn.srem('selected_%s' % user.id, *redis_carts.keys())
            return http.JsonResponse({'code': RETCODE.OK, 'errmsg': '购物车全选成功'})

        else:
            cart_str = request.COOKIES.get('carts')
            if cart_str:
                cart_dict = pickle.loads(base64.b64decode(cart_str.encode()))
            else:
                return http.HttpResponseForbidden('cookie购物车都没有,全选什么？')

            for sku_id in cart_dict:
                cart_dict[sku_id]['selected'] = selected
            cart_str = base64.b64encode(pickle.dumps(cart_dict)).decode()
            response = http.JsonResponse({'code':RETCODE.OK, 'errmsg': '购物车全选成功'})
            response.set_cookie('carts', cart_str)

            return response

class CartSimpleView(View):

    def get(self, request):
        user = request.user
        if user.is_authenticated:
            redis_conn = get_redis_connection('carts')
            redis_carts = redis_conn.hgetall('cart_%s' % user.id)
            selected_ids = redis_conn.smembers('selected_%s' % user.id)
            cart_dict = {}
            for sku_id_bytes in redis_carts:
                cart_dict[int(sku_id_bytes)] = {
                    'count': int(redis_carts[sku_id_bytes]),
                    'selected': sku_id_bytes in selected_ids
                }

        else:

            cart_str = request.COOKIES.get('carts')
            if cart_str:
                cart_dict = pickle.loads(base64.b64decode(cart_str.encode()))
            else:
                return render(request, 'cart.html')

        sku_qs = SKU.objects.filter(id__in=cart_dict.keys())
        sku_list = []
        for sku_model in sku_qs:
            count = cart_dict[sku_model.id]['count']
            sku_list.append({
                'id': sku_model.id,
                'name': sku_model.name,
                'default_image_url': sku_model.default_image.url,
                'count': count,
            })

        return http.JsonResponse({'code': RETCODE.OK, 'errmag': 'OK', 'cart_skus': sku_list})